import * as zrender from "zrender";

class Frame {
  constructor(editor) {
    this.editor = editor;
    this.w = 6;
    this.visible = true;
    this.createBar();
    this.initEvent();
    this.hide();
  }

  createBar() {
    const { w } = this;

    this.frame = new zrender.Rect({ style: { fill: "transparent" } });

    this.lefttopbar = new zrender.Rect({
      style: { fill: "#fff", stroke: "red", lineWidth: 1 },
      shape: { width: w, height: w },
      draggable: true,
      cursor: "nw-resize",
      z: 30001,
    });

    this.righttopbar = new zrender.Rect({
      style: { fill: "#fff", stroke: "red", lineWidth: 1 },
      shape: { width: w, height: w },
      draggable: true,
      cursor: "ne-resize",
      z: 30001,
    });

    this.leftbottombar = new zrender.Rect({
      style: { fill: "#fff", stroke: "red", lineWidth: 1 },
      shape: { width: w, height: w },
      draggable: true,
      cursor: "sw-resize",
      z: 30001,
    });

    this.rightbottombar = new zrender.Rect({
      style: { fill: "#fff", stroke: "red", lineWidth: 1 },
      shape: { width: w, height: w },
      draggable: true,
      cursor: "se-resize",
      z: 30001,
    });

    this.editor.add(this.lefttopbar);
    this.editor.add(this.leftbottombar);
    this.editor.add(this.righttopbar);
    this.editor.add(this.rightbottombar);
    this.editor.add(this.frame);
    this.hide();
  }

  initEvent() {
    const { lefttopbar, leftbottombar, righttopbar, rightbottombar } = this;
    let drag = false;
    let sx = 0;
    let sy = 0;
    let oldData = null;
    let rect = null;
    const bars = [lefttopbar, leftbottombar, righttopbar, rightbottombar];

    bars.forEach((bar, index) => {
      bar.on("dragstart", (e) => {
        rect = zrender.util.clone(this.box);
        drag = true;
        sx = e.offsetX;
        sy = e.offsetY;
        oldData = this.boxItem.getData();
        this.editor.status = "resizeNode";
      });

      bar.on("drag", (e) => {
        if (!drag) return;

        const dx = e.offsetX - sx;
        const dy = e.offsetY - sy;
        if (index == 0) {
          this.box.x = rect.x + dx;
          this.box.y = rect.y + dy;
          this.box.width = rect.width - dx;
          this.box.height = rect.height - dy;
        } else if (index == 1) {
          this.box.x = rect.x + dx;
          this.box.y = rect.y;
          this.box.width = rect.width - dx;
          this.box.height = rect.height + dy;
        } else if (index == 2) {
          this.box.x = rect.x;
          this.box.y = rect.y + dy;
          this.box.width = rect.width + dx;
          this.box.height = rect.height - dy;
        } else {
          this.box.x = rect.x;
          this.box.y = rect.y;
          this.box.width = rect.width + dx;
          this.box.height = rect.height + dy;
        }

        this.refreshGroup();
        this.boxSelect(this.box, this.boxItem);
        this.refreshBar();
        this.boxItem.refreshEdge();
        this.boxItem.nodeGroup?.refresh();
      });

      bar.on("dragend", () => {
        this.editor.zr.trigger("resizeNode", { oldData });
        drag = false;
        this.editor.status = "";
      });
    });

    document.addEventListener("mouseup", () => {
      if (!drag) return;
      drag = false;
      this.editor.status = "";
    });
  }

  boxSelect(box, boxItem) {
    box.x += 0.5;
    box.y += 0.5;
    box.width -= 1;
    box.height -= 1;
    this.box = box;
    this.boxItem = boxItem;

    this.frame.attr({
      position: [box.x, box.y],
      style: { stroke: "red", lineWidth: 1 },
      shape: { x: 0, y: 0, width: box.width, height: box.height },
    });

    this.show();
  }

  refreshBar() {
    const { w } = this;

    this.lefttopbar.attr({
      position: [this.box.x, this.box.y],
      shape: { x: -w / 2, y: -w / 2 },
    });

    this.righttopbar.attr({
      position: [this.box.x + this.box.width, this.box.y],
      shape: { x: -w / 2, y: -w / 2 },
    });

    this.leftbottombar.attr({
      position: [this.box.x, this.box.y + this.box.height],
      shape: { x: -w / 2, y: -w / 2 },
    });

    this.rightbottombar.attr({
      position: [this.box.x + this.box.width, this.box.y + this.box.height],
      shape: { x: -w / 2, y: -w / 2 },
    });
  }

  refreshGroup() {
    const { width, height, x, y } = this.box;
    const [posx, posy] = this.boxItem.position;

    if (this.boxItem.type == "ellipse") {
      const rx = width / 2;
      const ry = height / 2;
      const cx = x + rx;
      const cy = y + ry;

      this.boxItem.attr({
        shape: {
          cx: cx - posx,
          cy: cy - posy,
          rx,
          ry,
        },
      });
    } else if (this.boxItem.type == "image") {
      this.boxItem.attr({ position: [x, y], style: { width, height } });
    } else {
      this.boxItem.attr({ position: [x, y], shape: { x: 0, y: 0, width, height } });
    }
  }

  hide() {
    if (!this.visible) return;
    this.lefttopbar.hide();
    this.leftbottombar.hide();
    this.righttopbar.hide();
    this.rightbottombar.hide();
    this.frame.hide();
    this.visible = false;
  }

  show() {
    if (this.visible) return;
    this.lefttopbar.show();
    this.leftbottombar.show();
    this.righttopbar.show();
    this.rightbottombar.show();
    this.frame.show();
    this.visible = true;
  }
}

export default Frame;
